package com.borya.util;

import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.log4j.Logger;


import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public abstract class HTTPUtils {

	private static Logger log = Logger.getLogger(HTTPUtils.class);
	private static OkHttpClient httpClient;

	public static String sendPost(String url, String data) {
		log.info(url+":::send:::"+data);
		RequestBody body = RequestBody.create(null, data);
		Request request = new Request.Builder().url(url).post(body).build();
		try (Response response = httpClient.newCall(request).execute()) {
			if (response.code() == 200) {
				return response.body().string();
			} else {
				log.error(String.format("Response failure on http post: url=%s, data=%s, code=%s, message=%s, content:%s",
						url, data, response.code(), response.message(), response.body().string()));
				return null;
			}
		} catch (Exception e) {
			log.error(String.format("Catch exception on http post: url=%s, data=%s", url, data), e);
			return null;
		}
	}

	public static String sendPostUrlencode(String url, String data) {
		log.info(url+":::send:::"+data);
		RequestBody body = RequestBody.create(null, data);
		Request request = new Request.Builder().url(url).post(body)
				.addHeader("Content-Type", "application/x-www-form-urlencoded").build();
		try (Response response = httpClient.newCall(request).execute()) {
			if (response.code() == 200) {
				return response.body().string();
			} else {
				log.error(String.format("Response failure on http post: url=%s, data=%s, code=%s, message=%s, content:%s",
						url, data, response.code(), response.message(), response.body().string()));
				return null;
			}
		} catch (Exception e) {
			log.error(String.format("Catch exception on http post: url=%s, data=%s", url, data), e);
			return null;
		}
	}
	
	public static String sendGet(String url) {
		Request request = new Request.Builder().url(url).get().build();
		try (Response response = httpClient.newCall(request).execute()) {
			if (response.code() == 200) {
				return response.body().string();
			} else {
				log.error(String.format("Response failure on http get: url=%s, code=%s, message=%s, content:%s",
						url, response.code(), response.message(), response.body().string()));
				return null;
			}
		} catch (Exception e) {
			log.error(String.format("Catch exception on http get: url=%s", url), e);
			return null;
		}
	}
	
	public static byte[] sendGetReByte(String url) {
		Request request = new Request.Builder().url(url).get().build();
		try (Response response = httpClient.newCall(request).execute()) {
			if (response.code() == 200) {
				return response.body().bytes();
			} else {
				log.error(String.format("Response failure on http get: url=%s, code=%s, message=%s, content:%s",
						url, response.code(), response.message(), response.body().string()));
				return null;
			}
		} catch (Exception e) {
			log.error(String.format("Catch exception on http get: url=%s", url), e);
			return null;
		}
	}

	static {
		try {
			ConnectionPool connectionPool = new ConnectionPool(Runtime.getRuntime().availableProcessors() * 2, 5,
					TimeUnit.MINUTES);
			OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(1, TimeUnit.MINUTES)
					.readTimeout(1, TimeUnit.MINUTES).writeTimeout(1, TimeUnit.MINUTES).connectionPool(connectionPool);
			SSLContext sslContext = SSLContext.getInstance("TLS");
			X509TrustManager trustManager = new X509TrustManager() {

				@Override
				public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				}

				@Override
				public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				}

				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return new X509Certificate[0];
				}
			};
			sslContext.init(null, new TrustManager[] { trustManager }, new SecureRandom());
			SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
			HostnameVerifier hostnameVerifier = new HostnameVerifier() {

				@Override
				public boolean verify(String hostname, SSLSession session) {
					return true;
				}
			};
			httpClient = builder.sslSocketFactory(sslSocketFactory, trustManager).hostnameVerifier(hostnameVerifier)
					.build();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
